#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
@author: xjx
@time: 2023/10/12 23:58 
@file: drivingdata_load_to_database.py
@project: nanchangproject
@describe: 将csv文件的数据写入到数据库中
"""
import os
import sys
import django
import pandas as pd
import numpy as np

sys.path.append('../../')
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'nanchangproject.settings')
django.setup()  # 很关键的配置，必须先setup在导入models类

from drivinginfo.models import Drivinginfo


def load_to_database(csv_name: str) -> None:
    """
    @param csv_name: csv文件名称
    @return:
    """
    try:
        df = pd.read_csv(csv_name, low_memory=False)
    except Exception as e:
        print(e)
    else:
        origin_df = df[['VIN', '采集时间', '经度', '纬度', '车速', '大气压力', '发动机净输出扭矩或发动机实际扭矩/指示扭矩',
                          '摩擦扭矩', '发动机转速', '发动机燃料流量', 'SCR上游NOx传感器输出值', 'SCR下游NOx传感器输出值',
                          '反应剂余量', '进气量', 'SCR入口温度', 'SCR出口温度', 'DPF压差', '发动机冷却液温度', '剩余油量',
                          '累计里程', '定位有效状态', '发动机状态']].copy()
        unit = {'车速': 'km/h',
                '大气压力': 'kPa',
                '发动机净输出扭矩或发动机实际扭矩/指示扭矩': '%',
                '摩擦扭矩': '%',
                '发动机转速': 'RPM',
                '发动机燃料流量': 'L/h',
                'SCR上游NOx传感器输出值': 'ppm',
                'SCR下游NOx传感器输出值': 'ppm',
                '反应剂余量': '%',
                '进气量': 'kg/h',
                'SCR入口温度': '℃',
                'SCR出口温度': '℃',
                'DPF压差': 'kPa',
                '发动机冷却液温度': '℃',
                '剩余油量': '%',
                '累计里程': 'km'}
        # unit_list = [x for x in unit]
        selected_df = origin_df.copy()
        for col in origin_df.columns:
            if col in unit:
                col_unit = unit[col]  # 根据列标签筛选单位
                selected_df[col] = origin_df[col].str.split(col_unit).str[0]
        selected_df.drop(selected_df[selected_df['车速'] == '无效'].index, inplace=True)
        selected_df.drop(selected_df[selected_df['大气压力'] == '无效'].index, inplace=True)
        selected_df.drop(selected_df[selected_df['发动机净输出扭矩或发动机实际扭矩/指示扭矩'] == '无效'].index, inplace=True)
        selected_df.drop(selected_df[selected_df['摩擦扭矩'] == '无效'].index, inplace=True)
        selected_df.drop(selected_df[selected_df['发动机转速'] == '无效'].index, inplace=True)
        selected_df.drop(selected_df[selected_df['发动机燃料流量'] == '无效'].index, inplace=True)
        selected_df.drop(selected_df[selected_df['进气量'] == '无效'].index, inplace=True)
        selected_df.drop(selected_df[selected_df['DPF压差'] == '无效'].index, inplace=True)
        selected_df.drop(selected_df[selected_df['发动机冷却液温度'] == '无效'].index, inplace=True)
        selected_df = selected_df.replace({'无效': -10000})  # np.nan很难处理，建议改成一个很离谱的值，SCR的数据大多都是无效的
        selected_df.drop(selected_df[selected_df['VIN'].isnull()].index, inplace=True)
        selected_df.drop(selected_df[selected_df['车速'].isnull()].index, inplace=True)
        selected_df.drop(selected_df[selected_df['发动机燃料流量'].isnull()].index, inplace=True)
        # selected_df.drop(selected_df[selected_df['累计里程'].isnull()].index, inplace=True)
        # 对于发动机状态为nan,对进气量为0，则补偿为发动机状态关闭
        selected_df.loc[(selected_df['进气量'] == '0.0') & (pd.isna(selected_df['发动机状态'])), '发动机状态'] = '关闭'
        selected_df.loc[(selected_df['进气量'] != '0.0') & (pd.isna(selected_df['发动机状态'])), '发动机状态'] = '启动'
        selected_df = selected_df.reset_index(drop=True)  # 删除了某几行必须重置索引
        selected_df.fillna(method='ffill', inplace=True)  # 填充剩余的空白值
        # 第二行发动机状态为空值，但是dataframe中为float.nan
        # 发动机状态中存在空值，dataframe会以float.nan形式存在，建议使用空值填充
        df_data = selected_df.iloc[:, :].values
        # np.nan 在不同数据结构中的存在是不同的，在float中为null，在decimal中为NaN，在Char中为'nan'字符串
        info_list = []  # 创建更新列表
        for index, line in enumerate(df_data):
            print(f'数据正在写入,第{index}行')
            # 一行一行创建的效率比较低，建议使用bulk_create
            info_list.append(Drivinginfo(vin=line[0],
                                         data_time=line[1],
                                         longitude=line[2],
                                         latitude=line[3],
                                         car_speed=line[4],
                                         atmospheric_pressure=line[5],
                                         actual_torque=line[6],
                                         friction_torque=line[7],
                                         engine_speed=line[8],
                                         fuel_flow=line[9],
                                         scr_up_nox=line[10],
                                         scr_down_nox=line[11],
                                         reactive_agent=line[12],
                                         air_intake=line[13],
                                         scr_inlet_temperature=line[14],
                                         scr_outlet_temperature=line[15],
                                         dpf_pressure_difference=line[16],
                                         coolant_temperature=line[17],
                                         tank_level=line[18],
                                         accumulation_mile=line[19],
                                         location_status=line[20],
                                         engine_status=line[21]))
            # if index == 10:
            #     break
        try:
            Drivinginfo.objects.bulk_create(info_list)
            print('数据全部写入完毕')
        except Exception as e:
            print(e)


if __name__ == '__main__':
    load_to_database('D:\课题组相关\数据\轻卡数据下载0627\LETYBEG23MH043111\\2.csv')
